<!doctype html>
<html lang="zh-CN">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Insight Server API 文档</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
      margin: 0;
      padding: 0;
      background: #f7f8fa;
      color: #222;
    }

    header {
      background: #0d6efd;
      color: #fff;
      padding: 20px;
    }

    header h1 {
      margin: 0;
      font-size: 22px;
    }

    main {
      max-width: 980px;
      margin: 20px auto;
      padding: 0 16px 40px;
    }

    section {
      background: #fff;
      border: 1px solid #e5e7eb;
      border-radius: 8px;
      margin-bottom: 16px;
    }

    section h2 {
      font-size: 18px;
      margin: 0;
      padding: 14px 16px;
      border-bottom: 1px solid #e5e7eb;
    }

    .content {
      padding: 14px 16px;
    }

    .endpoint {
      border: 1px dashed #e5e7eb;
      border-radius: 8px;
      padding: 12px;
      margin: 12px 0;
    }

    .verb {
      display: inline-block;
      font-weight: 600;
      font-size: 12px;
      color: #fff;
      border-radius: 4px;
      padding: 2px 8px;
      margin-right: 8px;
    }

    .get {
      background: #198754;
    }

    .post {
      background: #0d6efd;
    }

    .put {
      background: #6f42c1;
    }

    .delete {
      background: #dc3545;
    }

    code,
    pre {
      background: #f3f4f6;
      border: 1px solid #e5e7eb;
      border-radius: 6px;
    }

    code {
      padding: 2px 4px;
    }

    pre {
      padding: 8px;
      overflow-x: auto;
    }

    .small {
      color: #666;
      font-size: 13px;
    }

    ul {
      margin: 8px 0;
    }

    li {
      margin: 4px 0;
    }

    a {
      color: #0d6efd;
      text-decoration: none;
    }

    a:hover {
      text-decoration: underline;
    }

    .quick-nav {
      position: sticky;
      top: 0;
      background: #fff;
      border-bottom: 1px solid #e5e7eb;
      padding: 8px 16px;
      z-index: 10;
    }

    .quick-nav a {
      margin-right: 12px;
      font-weight: 500;
    }
  </style>
</head>

<body>
  <header>
    <h1>Insight Server API 文档</h1>
    <div class="small">Base URL: <code>http://localhost:3000</code></div>
  </header>
  <nav class="quick-nav">
    <a href="#overview">概览</a>
    <a href="#file">文件模块</a>
    <a href="#i18n">国际化模块</a>
    <a href="#auth">认证模块</a>
    <a href="#news">新闻模块</a>
    <a href="#health">健康检查</a>
    <a href="#appendix">附录</a>
  </nav>
  <main>
    <section id="overview">
      <h2>概览</h2>
      <div class="content">
        <ul>
          <li>统一响应结构：<code>{ code, message, data }</code></li>
          <li>静态资源：<code>/uploads/</code>（上传文件访问），<code>/api-docs.html</code>（本文档）</li>
          <li>健康检查：<code>GET /health</code></li>
        </ul>
      </div>
    </section>

    <section id="file">
      <h2>文件模块 /file</h2>
      <div class="content">
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/file/upload</code>
          <div class="small">表单字段：<code>file</code>（multipart/form-data）<strong>（需要令牌）</strong></div>
          <pre><code>curl -s -i -X POST http://localhost:3000/file/upload \
            -H 'Authorization: Bearer &lt;JWT&gt;' \
            -F "file=@/绝对或相对路径/示例文件.ext"</code></pre>
          <div class="small">返回示例：</div>
          <pre><code>{
  "code": 200,
  "message": "上传成功",
  "data": { "url": "/uploads/file-xxxxxxxx.ext", "id": 1, "filename": "示例文件.ext", "size": 1234 }
}</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/file/list</code>
          <pre><code>curl -s -i http://localhost:3000/file/list</code></pre>
          <div class="small">返回：<code>{ records: [...], total: N }</code>，每条记录含 <code>url</code> 可直接访问。</div>
        </div>
        <div class="endpoint">
          <span class="verb delete">DELETE</span>
          <code>/file/:id</code>
          <pre><code>curl -s -i -X DELETE http://localhost:3000/file/123 \
            -H 'Authorization: Bearer &lt;JWT&gt;'</code></pre>
        </div>
      </div>
    </section>

    <section id="i18n">
      <h2>国际化模块 /i18n</h2>
      <div class="content">
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/i18n/list?current=1&amp;currentSize=10&amp;code=HOME_</code>
          <pre><code>curl -s -i "http://localhost:3000/i18n/list?current=1&amp;currentSize=10&amp;code=HOME_"</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/i18n/create</code>
          <pre><code>curl -s -i -X POST http://localhost:3000/i18n/create \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{
        "code":"HOME_TITLE",
        "remarks":"首页标题",
        "languageTexts":[
          {"languageTag":"zh-CN","message":"首页"},
          {"languageTag":"en-US","message":"Home"}
        ]
      }'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/i18n/update</code>
          <pre><code>curl -s -i -X POST http://localhost:3000/i18n/update \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{
        "code":"HOME_TITLE",
        "remarks":"首页标题(更新)",
        "languageTexts":[
          {"languageTag":"zh-CN","message":"首页(更新)"},
          {"languageTag":"en-US","message":"Home (Updated)"}
        ]
      }'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb delete">DELETE</span>
          <code>/i18n/delete/:code</code>
          <pre><code>curl -s -i -X DELETE http://localhost:3000/i18n/delete/HOME_TITLE \
            -H 'Authorization: Bearer &lt;JWT&gt;'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/i18n/import</code>
          <div class="small">仅支持 multipart/form-data 文件导入（字段名 <code>file</code>），自动识别 .json/.csv，可用 <code>format</code>
            覆盖：</div>
          <pre><code>curl -i -X POST http://localhost:3000/i18n/import \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -F "file=@tests/fixtures/i18n-import.json"</code></pre>
          <pre><code>curl -i -X POST http://localhost:3000/i18n/import \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -F "file=@tests/fixtures/i18n-import.csv"</code></pre>
          <pre><code>curl -i -X POST http://localhost:3000/i18n/import \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -F "file=@path/to/i18n.json" -F "format=json"</code></pre>
          <div class="small">CSV 表头需为：<code>code,languageTag,message,remarks</code></div>
        </div>
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/i18n/export?format=json&amp;languageTags=zh-CN,en-US</code>
          <pre><code>curl -s -i "http://localhost:3000/i18n/export?format=json&amp;languageTags=zh-CN,en-US"</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/i18n/export?format=csv</code>
          <pre><code>curl -s -i "http://localhost:3000/i18n/export?format=csv"</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/i18n/export 直接下载（download=true，可选 filename）</code>
          <div class="small">CSV 直接下载：</div>
          <pre><code>curl -i "http://localhost:3000/i18n/export?format=csv&amp;languageTags=zh-CN,en-US&amp;download=true&amp;filename=i18n-data"</code></pre>
          <div class="small">JSON 直接下载：</div>
          <pre><code>curl -i "http://localhost:3000/i18n/export?format=json&amp;languageTags=zh-CN&amp;download=true&amp;filename=i18n-data"</code></pre>
          <div class="small">说明：当 <code>download=true</code> 时，服务端设置 <code>Content-Type</code> 与
            <code>Content-Disposition</code>，浏览器会直接下载对应格式文件；不带 <code>download</code> 参数时，返回常规 JSON 响应。</div>
        </div>
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/i18n/:languageTag</code>
          <pre><code>curl -s -i http://localhost:3000/i18n/zh-CN</code></pre>
        </div>
      </div>
    </section>

    <section id="auth">
      <h2>认证模块 /auth</h2>
      <div class="content">
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/auth/captcha</code>
          <div class="small">用于登录前获取图形验证码，返回验证码图片与标识。</div>
          <div class="small">成功返回：</div>
          <pre><code>{
  "code": 200,
  "message": "获取成功",
  "data": {
    "id": "f6c2b9e0-10e3-4f2f-9a23-7d3c3b2c0c11",
    "image": "...",
    "expires_in": 120,
    "text": "BC4p5"
  }
}</code></pre>
          <div class="small">说明：</div>
          <ul class="small">
            <li><code>id</code> 为验证码标识；<code>image</code> 为 SVG 图片的 data URI；<code>expires_in</code> 为有效期秒数。</li>
            <li><code>text</code> 字段在开发环境返回用于调试，生产可忽略或不返回。</li>
          </ul>
          <pre><code>curl -s -i http://localhost:3000/auth/captcha</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/auth/login</code>
          <div class="small">请求体：</div>
          <pre><code>{
  "username": "admin",
  "password": "secret",
  "captcha_id": "f6c2b9e0-10e3-4f2f-9a23-7d3c3b2c0c11",
  "captcha_code": "BC4p5"
}</code></pre>
          <div class="small">成功返回：</div>
          <pre><code>{
  "code": 200,
  "message": "登录成功",
  "data": {
    "access_token": "<JWT>",
    "refresh_token": "<JWT>",
    "expires_in": 3600,
    "token_type": "Bearer",
    "scope": "read write",
    "info": {
      "userId": 1,
      "username": "admin",
      "type": "admin",
      "organizationId": 1,
      "nickname": "Admin",
      "avatar": "/path/avatar.png"
    },
    "attributes": {
      "permissions": ["read", "write"],
      "roleCodes": ["admin"]
    }
  }
}</code></pre>
          <div class="small">错误返回示例：</div>
          <pre><code>{ "code": 400, "message": "验证码错误", "data": null }</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"secret","captcha_id":"<ID>","captcha_code":"<CODE>"}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/auth/refresh</code>
          <div class="small">请求体：</div>
          <pre><code>{
  "refresh_token": "<JWT>"
}</code></pre>
          <div class="small">成功返回：</div>
          <pre><code>{
  "code": 200,
  "message": "令牌刷新成功",
  "data": {
    "access_token": "<JWT>",
    "expires_in": 3600,
    "token_type": "Bearer",
    "scope": "read write"
  }
}</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/auth/refresh \
  -H 'Content-Type: application/json' \
  -d '{"refresh_token":"<JWT>"}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/auth/logout</code>
          <div class="small">请求体：无</div>
          <div class="small">成功返回：</div>
          <pre><code>{
  "code": 200,
  "message": "登出成功",
  "data": null
}</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/auth/logout</code></pre>
        </div>
      </div>
    </section>

    <section id="news">
      <h2>新闻模块 /news</h2>
      <div class="content">
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/news/newsList?current=1&amp;currentSize=10</code>
          <div class="small">查询参数（可选，均为查询字符串）：</div>
          <pre><code>keywords               在 abstractReal 或 newsTitle 模糊匹配
 classReal              分类（1-5），支持多值，如 1,2,3
 addMode                采集方式：0=自动，1=人工
 isPublished            发布状态：0=未发布，1=已发布
 createTimeFrom         创建时间起（YYYY-MM-DD HH:mm:ss）
 createTimeTo           创建时间止（YYYY-MM-DD HH:mm:ss）
 timeRange              与上面二者互斥，格式：from,to
+ sortby                 0=按创建时间降序，1=按创建时间升序</code></pre>
          <div class="small">返回：</div>
          <pre><code>{
  "code": 200,
  "message": "获取成功",
  "data": {
    "records": [
      {
        "id": 1,
        "title": "标题",
        "newsTitle": "新闻标题",
        "abstractReal": "摘要",
        "classReal": 1,
        "classModel": "模型",
        "newsSource": "来源",
        "newsTime": "2024-01-01",
        "coverImage": "/uploads/xxx.png",
        "isSelect": 0,
        "addMode": 1,
        "siteName": "站点",
        "opPerson": "作者",
        "createTime": "2024-01-01 10:00:00",
        "pubTime": null,
        "isPublished": 0,
        "markContent": "markdown内容",
        "sourceUrl": "https://example.com"
      }
    ],
    "total": 1
  }
}</code></pre>
          <div class="small">示例：</div>
          <pre><code>curl -s -i "http://localhost:3000/news/newsList?current=1&amp;currentSize=10"</code></pre>
          <pre><code>curl -s -i "http://localhost:3000/news/newsList?current=1&amp;currentSize=10&amp;keywords=%E6%B5%8B%E8%AF%95%E6%96%B0%E9%97%BB"</code></pre>
          <pre><code>curl -s -i "http://localhost:3000/news/newsList?current=1&amp;currentSize=10&amp;classReal=2,3&amp;addMode=1&amp;isPublished=0&amp;sortby=1"</code></pre>
          <pre><code>curl -s -i "http://localhost:3000/news/newsList?current=1&amp;currentSize=10&amp;classReal=2,3&amp;addMode=1&amp;isPublished=0&amp;sortby=0"</code></pre>
          <pre><code>curl -s -i "http://localhost:3000/news/newsList?current=1&amp;currentSize=10&amp;sortby=1"</code></pre>
          <pre><code>curl -s -i "http://localhost:3000/news/newsList?current=1&amp;currentSize=10&amp;timeRange=2024-01-01%2000:00:00,2024-12-31%2023:59:59"</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/news/detail/:id</code>
          <div class="small">路径参数：<code>id</code>（必填，数字）。</div>
          <div class="small">成功返回（示例字段，实际对象更完整）：</div>
          <pre><code>{
  "code": 200,
  "message": "获取成功",
  "data": {
    "id": 1,
    "newsTitle": "第1条测试新闻：城市建设获得新进展",
    "newsSource": "光明日报",
    "newsTime": "2024-11-21 00:31:31",
    "coverImage": "https://placehold.co/600x400?text=News+1",
    "classReal": 4,
    "classModel": "经济发展",
    "abstractReal": "这是第1条新闻的摘要...",
    "title": "操作人写入测试",
    "markContent": "markdown内容...",
    "sourceUrl": "https://example.com/news/1",
    "isPublished": 1,
    "isSelect": 0,
    "createdAt": "2025-09-12 09:54:24",
    "updatedAt": "2025-10-29 02:46:20",
    "siteName": "人民网",
    "opPerson": "tester-admin",
    "createTime": "2025-06-02 16:52:32",
    "pubTime": "2024-10-14 22:45:27"
  }
}</code></pre>
          <div class="small">错误返回：<code>{ "code": 404, "message": "新闻不存在", "data": null }</code></div>
          <pre><code>curl -s -i "http://localhost:3000/news/detail/1"</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/insertNews</code>
          <div class="small">请求体（至少 <code>newsTitle</code> 或 <code>title</code> 其一）：</div>
          <pre><code>{
  "newsTitle": "新闻标题",
  "title": "标题",
  "abstractReal": "摘要",
  "classReal": 1,
  "classModel": "模型",
  "newsSource": "来源",
  "newsTime": "2024-01-01",
  "coverImage": "/uploads/xxx.png",
  "isSelect": 0,
  "addMode": 1,
  "siteName": "站点",
  "opPerson": "作者",
  "createTime": "2024-01-01 10:00:00",
  "pubTime": null,
  "isPublished": 0,
  "markContent": "markdown内容",
  "sourceUrl": "https://example.com"
}</code></pre>
          <div class="small">成功返回：</div>
          <pre><code>{ "code": 200, "message": "添加成功", "data": { "id": 123 } }</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/insertNews \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{"newsTitle":"新闻标题","classReal":1}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/updateNews</code>
          <div class="small">请求体（必须包含 <code>id</code>，其余为更新字段）：</div>
          <pre><code>{
  "id": 123,
  "title": "新标题",
  "isPublished": 1
}</code></pre>
          <div class="small">成功返回：</div>
          <pre><code>{ "code": 200, "message": "更新成功", "data": null }</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/updateNews \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{"id":123,"title":"新标题"}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/selectAllCountClassReal</code>
          <div class="small">返回示例：</div>
          <pre><code>{
  "code": 200,
  "message": "获取成功",
  "data": {
    "macroEnvironment": 10,
    "industryTrends": 5,
    "supplyChainDynamics": 3,
    "internationalEnergy": 2,
    "other": 1
  }
}</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/selectAllCountClassReal</code></pre>
        </div>

        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/updatePublish</code>
          <div class="small">请求体：</div>
          <pre><code>{ "id": 789, "waitPubTime": "2024-01-03 10:00:00" }</code></pre>
          <div class="small">成功返回：</div>
          <pre><code>{ "code": 200, "message": "更新成功", "data": null }</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/updatePublish \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{"id":789,"waitPubTime":"2024-01-03 10:00:00"}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/newsIssueTemplate</code>
          <div class="small">成功返回：</div>
          <pre><code>{
  "code": 200,
  "message": "获取成功",
  "data": {
    "template": "战略微头条 | (No.01) 2024.10.01-2024.10.08",
    "styles": "默认样式"
  }
}</code></pre>
          <div class="small">说明：模板号 No 按发布批次累计（参照 <code>publish_issue</code>），日期跨度固定为 7
            天（<code>PreviewDate-CurrentDate</code>）。</div>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/newsIssueTemplate</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/releaseList</code>
          <div class="small">返回当前选中列表：从 <code>news</code> 表查询 <code>is_select = 1</code>；请先通过
            <code>/news/updateNews</code> 设置选中。</div>
          <pre><code>{ "code": 200, "message": "获取成功", "data": { "list": [{"id":101,"newsTitle":"...","orderNews":10}], "total": 3 } }</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/releaseList</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/issueList</code>
          <div class="small">请求体（分页）：</div>
          <pre><code>{ "current": 1, "currentSize": 10 }</code></pre>
          <div class="small">成功返回：</div>
          <pre><code>{
  "code": 200,
  "message": "获取成功",
  "data": {
    "records": [
      { "issueNo": 6, "startDate": "2025.10.22", "endDate": "2025.10.29", "newsIds": [101,102,103] },
      { "issueNo": 5, "startDate": "2025.10.15", "endDate": "2025.10.22", "newsIds": [201,202] }
    ],
    "total": 12,
    "currentIssueNo": 6
  }
}</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/issueList \
  -H 'Content-Type: application/json' \
  -d '{"current":1,"currentSize":10}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/news/issueNews?issueNo=6</code>
          <div class="small">查询参数：<code>issueNo</code>（必填，数字）；无分页。</div>
          <div class="small">成功返回（按发布记录顺序，含期刊元数据）：</div>
          <pre><code>{
  "code": 200,
  "message": "获取成功",
  "data": {
    "records": [
      { "id": 101, "newsTitle": "...", "classReal": 1, "newsSource": "...", "newsTime": "..." },
      { "id": 102, "newsTitle": "...", "classReal": 2, "newsSource": "...", "newsTime": "..." }
    ],
    "total": 12,
    "issueTitle": "能源行业周报（第六期）",
    "issueCoverImage": "https://example.com/issue-6-cover.png",
    "issueDescription": "本期精选10条行业关键信息",
    "issuePublishTime": "2024-01-02 10:00:00",
    "issuePublisher": "admin"
  }
}</code></pre>
          <pre><code>curl -s -i "http://localhost:3000/news/issueNews?issueNo=6"</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/publishReleaseList</code>
          <div class="small"><strong>快速指南：发布后查询</strong>
            <div class="small">1) 发布期刊：<code>POST /news/publishReleaseList</code> 返回 <code>issueNo</code> 与当期
              <code>currentIssueNewsIds</code></div>
            <div class="small">2) 查询该期新闻：<code>POST /news/issueNews</code>，请求体
              <code>{"issueNo": &lt;返回的期刊号&gt;, "current": 1, "currentSize": 10}</code></div>
            <div class="small">如果未记录期刊号：先 <code>POST /news/issueList</code> 获取
              <code>data.currentIssueNo</code>，再查询对应期的新闻。</div>
            <pre><code># 获取最新期刊号
curl -s -X POST http://localhost:3000/news/issueList \
  -H 'Content-Type: application/json' \
  -d '{"current":1,"currentSize":10}'
# 查询该期新闻
curl -s -X POST http://localhost:3000/news/issueNews \
  -H 'Content-Type: application/json' \
  -d '{"issueNo":1,"current":1,"currentSize":10}'</code></pre>
            <div class="small">说明：发布后会清空选中列表（<code>release_list</code>），期刊新闻来源于 <code>publish_issue.news_ids</code> 与
              <code>news</code> 表。</div>
          </div>
          <div class="small">请求体：</div>
          <pre><code>{
  "waitPubTime": "2024-01-02 10:00:00",
  "issueTitle": "能源行业周报（第六期）",
  "issueCoverImage": "https://example.com/issue-6-cover.png",
  "issueDescription": "本期精选10条行业关键信息",
  "issuePublishTime": "2024-01-02 10:00:00",
  "issuePublisher": "admin"
}</code></pre>
          <div class="small">限制：<strong>每期刊最多10条新闻</strong>。当选中数量超过10时，接口将返回400错误。</div>
          <div class="small">成功返回（发布后将清空选中状态 <code>is_select</code>；<code>release_list</code> 不参与发布流程）：</div>
          <pre><code>{
  "code": 200,
  "message": "定时发布已创建并清空选中列表",
  "data": { "publishedCount": 10, "issueNo": 6, "currentIssueNewsIds": [101,102,103] }
}</code></pre>
          <div class="small">错误返回示例（超过10条）：</div>
          <pre><code>{
  "code": 400,
  "message": "每期刊发布的新闻数量不超过10，当前选中 12 条",
  "data": null
}</code></pre>
          <div class="small">示例：</div>
          <pre><code># 立即发布
curl -s -i -X POST http://localhost:3000/news/publishReleaseList \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{}'
# 定时发布
curl -s -i -X POST http://localhost:3000/news/publishReleaseList \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{"waitPubTime":"2024-01-02 10:00:00"}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/order</code>
          <div class="small">请求体：</div>
          <pre><code>{
  "list": [
    { "id": 1, "orderNews": 10 },
    { "id": 2, "orderNews": 20 }
  ]
}</code></pre>
          <div class="small">限制：<strong>选中列表数量不能超过10条</strong>；超过则返回400错误。</div>
          <div class="small">成功返回：</div>
          <pre><code>{ "code": 200, "message": "排序成功", "data": null }</code></pre>
          <div class="small">注意：该接口不影响发布顺序，仅保存 <code>orderNews</code>；发布时按 <code>news.created_at</code> 降序。<br />payload
            中的 <code>id</code> 指 <code>news.id</code>。</div>
          <div class="small">错误返回示例（超过10条）：</div>
          <pre><code>{ "code": 400, "message": "选中列表数量不能超过10条，当前选中 12 条", "data": null }</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/order \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{"list":[{"id":1,"orderNews":10},{"id":2,"orderNews":20}]}'</code></pre>
        </div>
        <div class="endpoint">
          <span class="verb post">POST</span>
          <code>/news/deleteNews</code>
          <div class="small">请求体：</div>
          <pre><code>{ "ids": [1, 2, 3] }</code></pre>
          <div class="small">成功返回：</div>
          <pre><code>{ "code": 200, "message": "删除成功", "data": null }</code></pre>
          <pre><code>curl -s -i -X POST http://localhost:3000/news/deleteNews \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer &lt;JWT&gt;' \
  -d '{"ids":[1,2,3]}'</code></pre>
        </div>
      </div>
    </section>

    <section id="health">
      <h2>健康检查</h2>
      <div class="content">
        <div class="endpoint">
          <span class="verb get">GET</span>
          <code>/health</code>
          <pre><code>curl -s -i http://localhost:3000/health</code></pre>
        </div>
      </div>
    </section>

    <section id="appendix">
      <h2>附录</h2>
      <div class="content small">
        <ul>
          <li>静态目录：<code>/uploads</code>（上传文件），<code>/public</code>（公共文档与资源）</li>
          <li>CSV 导入采用覆盖式：同一 <code>code</code> 会清理并重建对应语言记录</li>
          <li>错误响应包含 <code>code != 200</code> 与 <code>message</code> 描述</li>
        </ul>
      </div>
    </section>
  </main>
</body>

</html>